home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1993 April
/
CICA MS Windows - April 1993.iso
/
unzipped
/
programr
/
vbasic
/
hugary
/
hugearr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-11
|
28KB
|
769 lines
/************************************************************************
* *
* HUGEARR.DLL *
* *
* Huge array support for Microsoft Visual Basic *
* *
* By Mike Warning *
* *
* Modifications by Jonathan Zuck. *
* Modifications by Stephen Schmidt. *
* Modifications by End User Computing, Ltd. *
* *
************************************************************************/
#include <memory.h>
/* Define NOCOMM so that MSC compiler does not generate messages using Warning Level 4. */
#define NOCOMM
#include <windows.h>
struct ArrayDesc {
HANDLE handle; /* handle to global memory array */
int recsize; /* record size of array */
long ubound; /* upper bound of array */
int perseg; /* #elements per segment */
int redim; /* whether or not GlobalRealloc was successful */
long bsize; /* actual size in bytes of memory block allocated for array element storage */
};
typedef struct ArrayDesc *pDescrip;
typedef double currency; /* currency and double are the same size and will be treated the same */
/* All of the C comments which begin with "VBI:" or "VBB:" are placed into the files HUGEARR.VBI
and HUGEARR.BAS. */
/* VBI: ' An alternate set of definitions with more consistent names that you may want */
/* VBI: ' to consider using instead of those in HUGEARR.BAS. */
/* VBI: Global Const HA_OK = 0 */
/* VBI: Global Const HA_OUTOFMEMORY = -1 */
/* VBI: Global Const HA_TOMANYARRAYS = -2 */
/* VBI: Global Const HA_BADELEMENTSIZE = -3 ' no longer possible; left for backward compatibility. */
/* VBI: Global Const HA_SUBSCRIPT = -4 */
/* VBI: Global Const HA_BADARRAY = -5 */
/* VBI: Global Const HA_FILEOPENERROR = -7 */
/* VBI: Global Const HA_FILEWRITEERROR = -8 */
/* VBI: Global Const HA_FILEREADERROR = -9 */
/* VBB: ' The original set of definitions. */
/* VBB: Global Const HA_OK = 0 */
/* VBB: Global Const HA_OUTOFMEMORY = -1 */
/* VBB: Global Const HA_TOMANYARRAYS = -2 */
/* VBB: Global Const HA_BADELEMENTSIZE = -3 ' no longer possible; left for backward compatibility. */
/* VBB: Global Const HA_SUBSCRIPT = -4 */
/* VBB: Global Const HA_BADARRAY = -5 */
/* VBB: Global Const HA_FILEOPENERROR = -7 */
/* VBB: Global Const HA_FILEWRITEERROR = -8 */
/* VBB: Global Const HA_FILEREADERROR = -9 */
#define HA_OK 0
#define HA_OUTOFMEMORY -1
#define HA_TOMANYARRAYS -2
#define HA_BADELEMENTSIZE -3 /* no longer possible; left for backward compatibility */
#define HA_SUBSCRIPT -4
#define HA_BADARRAY -5
#define HA_FILEOPENERROR -7
#define HA_FILEWRITEERROR -8
#define HA_FILEREADERROR -9
HANDLE hLocalMem; /* handle to local memory */
int NumArrays; /* total number of arrays */
/************************************************************************
* LibMain - *
* Standard DLL constructor. Allocates all of local heap to store *
* array descriptors and then set the total number of arrays possible. *
************************************************************************/
int FAR pascal _export
LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
{
if (cbHeapSize > 0)
UnlockData(0);
/* Allocate memory for array descrips. */
hLocalMem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, LocalCompact((WORD) 65500));
if (hLocalMem == NULL)
/* Something happened, bomb out */
return 0;
/* calc total number of arrays */
NumArrays = (int) (LocalSize(hLocalMem) / sizeof(struct ArrayDesc));
return 1;
}
/************************************************************************
* WEP - *
* Standard DLL destructor. Free up local memory and quit. *
************************************************************************/
int FAR pascal _export
WEP(int bSystemExit)
{
LocalFree(hLocalMem);
return 1;
}
/********************************************************************
* GetFreeArray - *
* Searches the array descriptor table looking for a free entry. *
* It returns the index into the table if an entry is free or *
* HA_TOMANYARRAYS otherwise. pArray is the pointer to the start of *
* the table. *
********************************************************************/
int
GetFreeArray(pDescrip pArray)
{
int i = 0;
/* loop until found or out of entries */
while (i < NumArrays && pArray -> handle != NULL)
{
++pArray;
++i;
}
if (i == NumArrays)
/* didn't find a spot */
return HA_TOMANYARRAYS;
/* found one, return index to it */
return i;
}
#define HugeElementOffset(ELEMNO, PERSEG, RECSIZE) \
ELEMNO / (long) PERSEG * 0x10000L \
+ ELEMNO % (long) PERSEG * (long) RECSIZE
/********************************************************************
* HugeAlloc - *
* Allocates (or reallocates) global memory for an array. The size *
* of the array is recsize * (ubound + 1) bytes. The information *
* for the array is stored in the array descriptor pointed to by *
* 'pArray'. *
********************************************************************/
int
HugeAlloc(pDescrip pArray, int recsize, long ubound, BOOL realloc)
{
int perseg; /* #elements per segment */
long newsiz; /* actual size of array */
HANDLE handle; /* temp handle for alloc */
/* ubound = #elements - 1 */
++ubound;
/* #elements per segment. */
perseg = (int) (0x10000L / (long) recsize);
/* size of array in bytes */
newsiz = HugeElementOffset(ubound, perseg, recsize);
if (!realloc)
/* allocate a new array */
handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, newsiz);
else
#ifndef REDIMUAES
/* attempt to reallocate the existing array */
/* TO HUGEARR USERS RECEIVING UAE'S DURING CALLS TO HugeRedim: Define REDIMUAES somehow then recompile. */
if ((handle = GlobalReAlloc(pArray -> handle, newsiz, GMEM_MOVEABLE || GMEM_ZEROINIT)) != NULL)
pArray -> redim = TRUE;
else
#endif
/* existing array could not be reallocated--attempt to create a new one */
if ((handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, newsiz)) != NULL)
/* new array to replace the existing one was allocated okay */
{
BYTE _huge *FmBegin;
BYTE _huge *ToBegin;
long numcopy; /* minimum of #elements in old & new array */
long curelem; /* current element during copy */
long ElemOff; /* offset of current elements for copy */
/* get pointers to the beginning of the existing and new arrays */
FmBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
ToBegin = (BYTE _huge *) GlobalLock(handle);
/* size of original array is pArray->ubound + 1; size of new one is ubound */
numcopy = (ubound < pArray->ubound + 1L) ? ubound : pArray->ubound + 1L;
/* copy each element from old array to new array, up to the min. # of elements in both arrays. */
for (curelem = 0; curelem < numcopy; curelem++)
{
/* byte offset of current numbered element from beginning of memory block */
ElemOff = HugeElementOffset(curelem, perseg, recsize);
_fmemcpy(ToBegin + ElemOff, FmBegin + ElemOff, recsize);
}
GlobalUnlock(handle);
GlobalUnlock(pArray -> handle);
/* free old array */
GlobalFree(pArray -> handle);
pArray -> redim = FALSE;
}
if (handle == NULL)
/* out of memory */
return HA_OUTOFMEMORY;
pArray -> bsize = GlobalSize(handle);
/* save new handle */
pArray -> handle = handle;
/* save element size */
pArray -> recsize = recsize;
/* ubound = #elements - 1 */
pArray -> ubound = ubound - 1;
pArray -> perseg = perseg;
return HA_OK;
}
/************************************************************************
* HugeDim - *
* Dimensions a new array. The size of the array is *
* (recsize * ubound+1). Recsize is the size in bytes of each element in *
* the array and ubound is the upper bound of the array. All arrays have *
* a lower bound of 0. *
************************************************************************/
/* VBI: Declare Function MSHugeDim% Lib "hugearr.dll" Alias "HugeDim" (ByVal recsize%, ByVal limit&) */
/* VBB: Declare Function HugeDim% Lib "hugearr.dll" (ByVal recsize%, ByVal limit&) */
int FAR pascal _export
HugeDim(int recsize, long ubound)
{
int hArray; /* handle to array to dimension */
pDescrip pArray; /* pointer to array descriptor */
int ret; /* return value from HugeAlloc */
pArray = (pDescrip) LocalLock(hLocalMem);
/* find a free array */
if ((hArray = GetFreeArray(pArray)) == HA_TOMANYARRAYS)
{
/* couldn't find one, return error.*/
LocalUnlock(hLocalMem);
return HA_TOMANYARRAYS;
}
/* allocate new array */
ret = HugeAlloc(pArray + hArray, recsize, ubound, FALSE);
LocalUnlock(hLocalMem);
/* if an error occured during alloc */
if (ret < 0)
/* return the error, else */
return ret;
else
/* return the handle to the array */
/* VB users think handles start at 1 */
return hArray + 1;
}
#define DecCheckHandle \
/* VB users think hArray begins at 1 */ \
if (--hArray < 0 || hArray >= NumArrays) \
/* illegal array handle */ \
return HA_BADARRAY;
#define CheckNotAllocYet \
if (pArray -> handle == NULL) \
{ \
/* array hasn't been allocated */ \
LocalUnlock(hLocalMem); \
return HA_BADARRAY; \
}
#define CheckSubscript(MAX) \
if (pArray -> ubound < MAX || element < 0) \
{ \
/* subscript out of range */ \
LocalUnlock(hLocalMem); \
return HA_SUBSCRIPT; \
}
/************************************************************************
* HugeRedim - *
* Redimenions the given array to have the new 'ubound'. The old *
* recsize is kept. All data in the array is preserved and any new data *
* (created by expanding the array) is initialized to 0. *
************************************************************************/
/* VBI: Declare Function MSHugeRedim% Lib "hugearr.dll" Alias "HugeRedim" (ByVal hArray%, ByVal limit&) */
/* VBB: Declare Function HugeRedim% Lib "hugearr.dll" (ByVal hArray%, ByVal limit&) */
int FAR pascal _export
HugeRedim(int hArray, long ubound)
{
pDescrip pArray; /* pointer to array desciptor */
register ret; /* return code of HugeAlloc */
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
if (pArray -> handle != NULL)
/* reallocate array */
ret = HugeAlloc(pArray, pArray -> recsize, ubound, TRUE);
else
/* array has never been allocated */
ret = HA_BADARRAY;
LocalUnlock(hLocalMem);
return ret;
}
/********************************************************************
* GetHugeEl - *
* Retrieves an element of the array storing it into the buffer *
* pointed to by 'buffer'. hArray is the index into the descriptor *
* table of the array, element is the element to get. *
* *
* NOTE: there is absolutely no type checking done on the buffer. *
* It is up to the programmer to make sure it points to the *
* correct data type. *
********************************************************************/
/* VBI: Declare Function MSHugeGet% Lib "hugearr.dll" Alias "GetHugeEl" (ByVal Index%, ByVal el&, buffer As Any) */
/* VBB: Declare Function GetHugeEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, buffer As Any) */
int FAR pascal _export
GetHugeEl(int hArray, long element, BYTE FAR *buffer)
{
BYTE _huge *ptr; /* pointer to array element */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
/* point to proper descriptor */
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
CheckSubscript(element)
/* calculate pointer to element */
ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
/* add offset of element */
ptr += HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* copy data */
_fmemcpy(buffer, ptr, pArray -> recsize);
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
return HA_OK;
}
/* Same as GetHugeEl, except that it can copy multiple elements at one time. */
/* VBI: Declare Function MSHugeGetNum% Lib "hugearr.dll" Alias "GetHugeNEl" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
/* VBB: Declare Function GetHugeNEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
int FAR pascal _export
GetHugeNEl(int hArray, long element, int nelem, BYTE FAR *buffer)
{
BYTE _huge *ToBegin;
BYTE _huge *ToElem; /* pointer to array element */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
/* point to proper descriptor */
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
CheckSubscript(element + nelem - 1)
/* calculate pointer to element */
ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
while (nelem-- > 0)
{
ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* copy one element of data */
_fmemcpy(buffer, ToElem, pArray -> recsize);
/* increment pointer to VB array to point to next element. */
buffer += pArray -> recsize;
element ++;
}
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
return HA_OK;
}
/********************************************************************
* SetHugeEl - *
* Sets the value of an array element. This routine is exactly *
* the same as 'GetHugeEl' except that the memory copy is resversed. *
********************************************************************/
/* VBI: Declare Function MSHugeSet% Lib "hugearr.dll" Alias "SetHugeEl" (ByVal Index%, ByVal el&, buffer As Any) */
/* VBB: Declare Function SetHugeEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, buffer As Any) */
int FAR pascal _export
SetHugeEl(int hArray, long element, BYTE FAR *buffer)
{
BYTE _huge *ptr; /* pointer to array element */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
/* point to proper descriptor */
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
CheckSubscript(element)
/* calculate pointer to element */
ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
/* add offset of element */
ptr += HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* copy data */
_fmemcpy(ptr, buffer, pArray -> recsize);
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
return HA_OK;
}
/* Same as SetHugeEl, except that it can copy multiple elements at one time. */
/* VBI: Declare Function MSHugeSetNum% Lib "hugearr.dll" Alias "SetHugeNEl" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
/* VBB: Declare Function SetHugeNEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
int FAR pascal _export
SetHugeNEl(int hArray, long element, int nelem, BYTE FAR *buffer)
{
BYTE _huge *ToBegin;
BYTE _huge *ToElem; /* pointer to array element */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
/* point to proper descriptor */
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
CheckSubscript(element + nelem - 1)
/* calculate pointer to element */
ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
while (nelem-- > 0)
{
ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* copy one element of data */
_fmemcpy(ToElem, buffer, pArray -> recsize);
/* increment pointer to VB array to point to next element. */
buffer += pArray -> recsize;
element ++;
}
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
return HA_OK;
}
/********************************************************************
* HugeErase - *
* Deletes an array and marks it as free in the descriptor table. *
* 'hArray' is the array to erase. *
********************************************************************/
/* VBI: Declare Function MSHugeErase% Lib "hugearr.dll" Alias "HugeErase" (ByVal hArray%) */
/* VBB: Declare Function HugeErase% Lib "hugearr.dll" (ByVal hArray%) */
int FAR pascal _export
HugeErase(int hArray)
{
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
/* free the memory */
GlobalFree(pArray -> handle);
pArray -> handle = NULL;
LocalUnlock(hLocalMem);
return HA_OK;
}
/********************************************************************
* NumHugeArrays - *
* Returns the number of free entries in the array descriptor table*
********************************************************************/
/* VBI: Declare Function MSHugeNumArrays% Lib "hugearr.dll" Alias "NumHugeArrays" () */
/* VBB: Declare Function NumHugeArrays% Lib "hugearr.dll" () */
int FAR pascal _export
NumHugeArrays(void)
{
pDescrip pArray; /* pointer to current descriptor */
int num, i; /* number free so far */
pArray = (pDescrip) LocalLock(hLocalMem);
for (i = 0, num = 0; i < NumArrays; i++, pArray++)
if (pArray -> handle == NULL)
++num;
LocalUnlock(hLocalMem);
return num;
}
/********************************************************************
* HugeUbound - *
* Returns the upper bound of a given array *
********************************************************************/
/* VBI: Declare Function MSHugeUbound& Lib "hugearr.dll" Alias "HugeUBound" (ByVal hArray%) */
/* VBB: Declare Function HugeUbound& Lib "hugearr.dll" (ByVal hArray%) */
long FAR pascal _export
HugeUbound(int hArray)
{
pDescrip pArray; /* pointer to array descriptor */
long ubound; /* upper bound of array */
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
ubound = pArray -> ubound;
LocalUnlock(hLocalMem);
return ubound;
}
/********************************************************************
* HugeInt - *
* Same as GetHugeEl except that it explicitly returns an integer. *
* Use this function when you are in an expression such as: *
* i% = 5 * HugeInt(4, 5) *
* *
* NOTE: Because the user could store anything in the array element, *
* they will not know if the value returned is a real value or *
* if an error occured. Use GetHugeEl if the error code must *
* be checked. *
********************************************************************/
/* VBI: Declare Function MSHugeGetInt% Lib "hugearr.dll" Alias "HugeInt" (ByVal hArray%, ByVal el&) */
/* VBB: Declare Function HugeInt% Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
int FAR pascal _export
HugeInt(int hArray, long element)
{
int retval;
GetHugeEl(hArray, element, (BYTE FAR *) &retval);
return retval;
}
/********************************************************************
* HugeLong - *
* Returns an element of a long integer array. (re. HugeInt) *
********************************************************************/
/* VBI: Declare Function MSHugeGetLong& Lib "hugearr.dll" Alias "HugeLong" (ByVal hArray%, ByVal el&) */
/* VBB: Declare Function HugeLong& Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
long FAR pascal _export
HugeLong(int hArray, long element)
{
long retval;
GetHugeEl(hArray, element, (BYTE FAR *) &retval);
return retval;
}
/********************************************************************
* HugeSingle - *
* Returns an element of a single precesion array. (re. HugeInt) *
********************************************************************/
/* VBI: Declare Function MSHugeGetSingle! Lib "hugearr.dll" Alias "HugeSingle" (ByVal hArray%, ByVal el&) */
/* VBB: Declare Function HugeSingle! Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
float FAR pascal _export
HugeSingle(int hArray, long element)
{
float retval;
GetHugeEl(hArray, element, (BYTE FAR *) &retval);
return retval;
}
/********************************************************************
* HugeDouble - *
* Returns an element of a double precesion array. (re. HugeInt) *
********************************************************************/
/* VBI: Declare Function MSHugeGetDouble# Lib "hugearr.dll" Alias "HugeDouble" (ByVal hArray%, ByVal el&) */
/* VBB: Declare Function HugeDouble# Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
double FAR pascal _export
HugeDouble(int hArray, long element)
{
double retval;
GetHugeEl(hArray, element, (BYTE FAR *) &retval);
return retval;
}
/********************************************************************
* HugeCurrency - *
* Returns an element of a currency array. (re. HugeInt) *
********************************************************************/
/* VBI: Declare Function MSHugeGetCurrency@ Lib "hugearr.dll" Alias "HugeCurrency" (ByVal hArray%, ByVal el&) */
/* VBB: Declare Function HugeCurrency@ Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
currency FAR pascal _export
HugeCurrency(int hArray, long element)
{
currency retval;
GetHugeEl(hArray, element, (BYTE FAR *) &retval);
return retval;
}
#ifdef DEBUG
/* Functions left from when I was debugging my own HugeRedim problems. --SJS */
/* Return 1 if the last HugeRedim successfully called GlobalRealloc, or
return 0 if it had to call HugeAlloc and copy over elements. */
int FAR pascal _export
HugeRedimOk(int hArray)
{
pDescrip pArray; /* pointer to array descriptor */
int RtnVal;
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
RtnVal = pArray -> redim;
LocalUnlock(hLocalMem);
return RtnVal;
}
/* Return actual size in bytes of the global memory block that was
allocated for storing array elements */
long FAR pascal _export
HugeSize(int hArray)
{
pDescrip pArray; /* pointer to array descriptor */
long RtnVal;
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
RtnVal = pArray -> bsize;
LocalUnlock(hLocalMem);
return RtnVal;
}
#endif
/********************************************************************
* HugeSave - Saves the specified number of elements to a file *
* Returns the number of items saved. *
* *
* NB! HugeSave does not Erase the Huge Array. *
********************************************************************/
/* VBI: Declare Function MSHugeSave& Lib "hugearr.dll" Alias "HugeSave" (ByVal hArray%, ByVal NEl&, ByVal RecLen%, ByVal Fn$) */
/* VBB: Declare Function HugeSave& Lib "hugearr.dll" (ByVal hArray%, ByVal NEl&, ByVal RecLen%, ByVal Fn$) */
long FAR pascal _export
HugeSave(int hArray, long nelements, int OutLen, LPSTR FileSpec)
{
int hSaveFile; /* handle to the save file */
BYTE _huge *FmBegin; /* pointer for first element */
BYTE _huge *FmElem; /* pointer to array element */
long element; /* element in the huge array */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
if (pArray -> ubound + 1 < nelements || nelements < 0)
{
/* subscript out of range */
LocalUnlock(hLocalMem);
return HA_SUBSCRIPT;
}
/* Open the file */
hSaveFile = _lopen(FileSpec, OF_WRITE);
if (hSaveFile < 0)
{
LocalUnlock(hLocalMem);
return HA_FILEOPENERROR;
}
/* calculate pointer to element */
FmBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
for(element = 0L; element < nelements; element++)
{
FmElem = FmBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* Write out the record */
if(_lwrite(hSaveFile, FmElem, OutLen) < 0)
{
element = HA_FILEWRITEERROR;
break;
}
}
/* Wrap up and return */
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
_lclose(hSaveFile);
return element;
}
/********************************************************************
* HugeLoad - Loads a Huge Array from the specified file *
* Returns the number of elements loaded *
* *
* NB! The array must have been allocated and be of sufficient *
* NB! size to hold the array. *
********************************************************************/
/* VBI: Declare Function MSHugeLoad& Lib "hugearr.dll" Alias "HugeLoad" (ByVal hArray%, ByVal RecLen%, ByVal Fn$) */
/* VBB: Declare Function HugeLoad& Lib "hugearr.dll" (ByVal hArray%, ByVal RecLen%, ByVal Fn$) */
long FAR pascal _export
HugeLoad(int hArray, int InLen, LPSTR FileSpec)
{
int BytesRead; /* number of bytes read from the file */
int hLoadFile; /* handle to the save file */
BYTE _huge *ToBegin; /* pointer for first element */
BYTE _huge *ToElem; /* pointer to array element */
long element; /* element in the huge array */
pDescrip pArray; /* pointer to array descriptor */
DecCheckHandle
pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
CheckNotAllocYet
/* Open the file */
if((hLoadFile = _lopen(FileSpec, OF_READ)) < 0)
{
LocalUnlock(hLocalMem);
return HA_FILEOPENERROR;
}
ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
for(element = 0L; element <= pArray -> ubound ; element++)
{
/* calculate pointer to element */
ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
/* Read the record */
BytesRead = _lread(hLoadFile, ToElem, InLen);
if (BytesRead < 0)
element = HA_FILEREADERROR;
if (BytesRead <= 0)
break;
}
/* Wrap up and return */
GlobalUnlock(pArray -> handle);
LocalUnlock(hLocalMem);
_lclose(hLoadFile);
return element;
}